<template>
  <vue-draggable-resizable
    :grid="grids"
    :w="parseInt(style.width)"
    :h="parseInt(style.height)"
    :x="parseInt(style.x)"
    :y="parseInt(style.y)"
    @dragging="onDrag"
    @resizing="onResize"
    :parent="true"
    @activated="onActivated"
    @deactivated="onDeactivated"
  >
    <i class="el-icon-error removecomponents" @click="remove"></i>
    <el-table
      class="sys-tabel"
      :header-row-style="{'color': color}"
      :style="{'color': color}"
      v-if="chartType === 'table'"
      :data="tablelist"
      :height="parseInt(style.height)"
    >
      <el-table-column
        :key="column.field_name"
        v-for="column in columns"
        :prop="column.field_name"
        :label="column.show_name"
      ></el-table-column>
    </el-table>
    <div
      :style="component.bsChartInfo.wordInfoJSON.css | fixpx"
      v-else-if="chartType === 'word' && component.bsChartInfo.wordInfoJSON.word.indexOf('YYYY') > -1"
    >{{time}}</div>
    <div
      :style="component.bsChartInfo.wordInfoJSON.css | fixpx"
      v-else-if="chartType === 'word' && component.bsChartInfo.wordInfoJSON.word.indexOf('天气') > -1"
      v-html="weather"
    ></div>
    <svg :width="parseInt(style.width)" :height="parseInt(style.height)" 
      v-else-if="chartType === 'hots'"
    >
      <a v-for='(tag, index) in hots.tags' :key="tag.name">
        <text :x='tag.x' :y='tag.y' :font-size='tag.size' :fill="hots.colors[index%5]" :fill-opacity='((400+tag.z)/600)'>{{tag.text}}</text>
      </a>
    </svg>
    <input
      :style="component.bsChartInfo.wordInfoJSON.css | fixpx"
      v-else-if="chartType === 'word'"
      type="text"
      v-model="component.bsChartInfo.wordInfoJSON.word"
      class="wordediter"
    />
    <div
      v-else
      :id="id"
      :style="{'width': parseInt(style.width) + 'px', 'height': parseInt(style.height) + 'px', 'border': style.border ? '1px solid ' + style.border : 'none' }"
    ></div>
    <slot name="foot" style="margin-top: 40px;"></slot>
  </vue-draggable-resizable>
</template>
<script>
import echarts from "echarts";
import { mapMutations } from "vuex";
import Services from "@/services";
import moment from "moment";
import citys from "@/assets/weather_city.json";
export default {
  data() {
    return {
      echart: null,
      chartType: "chart",
      tablelist: [],
      columns: [],
      timeout: null,
      weather: "",
      hots: {
        RADIUS: 0,
        speedX: Math.PI / 360,
        speedY: Math.PI / 360,
        colors: ["#e86e6e", "#c8b566", "#6ee8bf", "#7e6654", "#6eafe8"],
        tags: [],
        playtime: 0,
        playtimeout: null
      }
    };
  },
  props: {
    component: Object,
    scale: Number,
    grid: Number,
    handleActive: Function,
    bsId: Number,
    color: String,
  },
  filters: {
    fixpx(css) {
      if (typeof css.fontSize === "number") {
        css.fontSize = css.fontSize + "px";
        return css;
      } else {
        return css;
      }
    }
  },
  computed: {
    time() {
      return moment().format(this.component.bsChartInfo.wordInfoJSON.word);
    },
    id() {
      return "echart" + this.component.bsChartInfo.id;
    },
    grids() {
      return [this.grid, this.grid];
    },
    style() {
      try {
        let chartConfig = JSON.parse(
          this.component.bsChartComponent.chartConfig
        );
        return {
          width: this.component.bsChartInfo.width,
          height: this.component.bsChartInfo.height,
          x: this.component.bsChartInfo.x,
          y: this.component.bsChartInfo.y,
          border:
            chartConfig.style && chartConfig.style.border
              ? chartConfig.style.border
              : null
        };
      } catch (error) {
        return {
          width: this.component.bsChartInfo.width,
          height: this.component.bsChartInfo.height,
          x: this.component.bsChartInfo.x,
          y: this.component.bsChartInfo.y
        };
      }
    },
    CX() {
      try {
        let chartConfig = JSON.parse(
          this.component.bsChartComponent.chartConfig
        );
        return this.component.bsChartInfo.width / 2;
      } catch (error) {
        return 0;
      }
    },
    CY() {
      try {
        let chartConfig = JSON.parse(
          this.component.bsChartComponent.chartConfig
        );
        return this.component.bsChartInfo.height / 2;
      } catch (error) {
        return 0;
      }
    }
  },
  mounted() {
    moment.locale("zh-cn")
    this.createChart()
  },
  methods: {
    ...mapMutations({
      CHARTS_UPDATE: "charts/UPDATE"
    }),

    // 构建该组件
    createChart() {
      this.echart = echarts.init(document.getElementById(this.id));
      this.echart.clear();

      if (this.component.bsChartComponent.chartType == 1) {
        // 表格
        this.chartType = "table";
        Services.CHARTS_OPTION({
          componentId: this.component.bsChartInfo.componentId,
          title: this.component.bsChartInfo.name,
          bsId: this.bsId
        }).then(res => {
          this.columns = res.dataMapping;
          this.tablelist = res.dataValue;
        });
      } else if (this.component.bsChartComponent.chartType == 20) {
        // 文字
        this.chartType = "word";
        if (this.component.bsChartInfo.wordInfoJSON.word.indexOf("天气") > -1) {
          let city = this.component.bsChartInfo.wordInfoJSON.word;
          city = city.replace("天气", "");
          let citycode = !1;
          for (let i = 0; i < citys.length; i++) {
            if (citys[i].city_name == city) {
              citycode = citys[i].city_code;
            }
          }
          if (citycode) {
            Services.WEATHER({
              cityCode: citycode
            }).then(res => {
              var todayWeather = res.data.forecast[0];
              var low = todayWeather.low.replace("低温 ", "");
              var high = todayWeather.high.replace("高温 ", "");
              this.weather =
                todayWeather.type +
                "&nbsp;&nbsp;" +
                low +
                "~" +
                high +
                "&nbsp;&nbsp;" +
                todayWeather.fx +
                todayWeather.fl;
            });
          }
        }
      } else {
        // 图表
        this.chartType = "chart";
        Services.CHARTS_OPTION({
          componentId: this.component.bsChartInfo.componentId,
          title: this.component.bsChartInfo.name,
          bsId: this.bsId
        })
          .then(res => {
            let chartConfig = JSON.parse(
              this.component.bsChartComponent.chartConfig
            );
            if (this.component.bsChartComponent.chartType == 7) {
              // 如果是图表里的地图
              let mapjson = chartConfig.adcode;
              let map = require("@/assets/map/" + mapjson + "_full.json");
              echarts.registerMap("MAPS", map);
              res.geo.zoom = 1;
              res.geo.scaleLimit = { min: 1, max: 3 };
              res.geo.roam = true;
            }
            if (
              this.component.bsChartComponent.chartType == 2 ||
              this.component.bsChartComponent.chartType == 10
            ) {
              // 设置柱状图表 宽度
              res.series.forEach(series => {
                series.barWidth = chartConfig.barWidth
                  ? chartConfig.barWidth
                  : "auto";
                return series;
              });
            }
            if (this.component.bsChartComponent.chartType == 3) {
              //线性图表 设置渐变
              res.series.forEach(
                series => (series = this.setAreaStyle(series))
              );
            }
            if (
              this.component.bsChartComponent.chartType == 10 ||
              this.component.bsChartComponent.chartType == 11
            ) {
              const CbarChartConfig = JSON.parse(
                this.component.bsChartComponent.chartConfig
              );
              if (
                CbarChartConfig.style &&
                typeof CbarChartConfig.style.color != "undefined"
              ) {
                res.color = CbarChartConfig.style.color;
              }
            }
            // if (this.component.bsChartComponent.chartType == 11) { //线性图表 设置渐变
            //   res.series[2].data[0].value = 30;
            //   res.series[2].data[1].value = 70;
            //   res.series[2].data[1].itemStyle = {"color": "rgba(0,0,0,0)"},
            //   res.color = '#ff0000'
            //   res.title.textStyle.color = '#ff0000'
            //   res.title.x = 'center'
            //   res.title.y = 'center'
            // }
            if (this.component.bsChartComponent.chartType == 12) {
              this.chartType = 'hots'
              // 如果是热词
              this.hots.tags = res.data
              this.startRotate()
            } else {
              this.echart.setOption(res);
            }
            
          })
          .catch(error => {
            console.log(error);
            document.getElementById(this.id).innerHTML =
              '<div style="font-size:18px;color:#ff0000;text-align:center;margin-top:20px;">数据源获取数据失败。</div>';
          });
      }
    },
    // 拖拽
    onDrag(x, y) {
      let componentClone = Object.assign({}, this.component);
      let newconfig = {
        x: x,
        y: y
      };
      Object.assign(componentClone.bsChartInfo, newconfig);
      this.CHARTS_UPDATE(componentClone);
    },
    // 放大或缩小
    onResize(x, y, width, height) {
      if (this.component.bsChartComponent.chartType == 20) {
        this.component.bsChartInfo.wordInfoJSON.css.fontSize = Math.floor(
          height / 1.7
        );
      }
      let componentClone = Object.assign({}, this.component);
      let newconfig = {
        x: x,
        y: y,
        width: width ? width : componentClone.bsChartInfo.width,
        height: height ? height : componentClone.bsChartInfo.height
      };
      Object.assign(componentClone.bsChartInfo, newconfig);
      this.CHARTS_UPDATE(componentClone);
    },
    // 唤醒配置
    onActivated() {
      this.handleActive(this.component);
    },
    onDeactivated() {},
    // 删除
    remove() {
      this.$emit("remove", this.component.bsChartInfo.id);
    },
    // 设置line图标的渐变
    setAreaStyle(series) {
      let color = series.color;
      if (color) {
        series.areaStyle = {
          normal: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              {
                offset: 0,
                color: color + "FF"
              },
              {
                offset: 0.5,
                color: color + "7F"
              },
              {
                offset: 1,
                color: color + "00"
              }
            ])
          }
        };
      }
      return series;
    },
    startRotate() {
      // console.log(this.scale)
      let tagsNum = this.hots.tags.length
      this.hots.RADIUS = Math.min(parseInt(this.style.width), parseInt(this.style.height)) / 2
      var tags = [];
      var colors = ["#e86e6e", "#c8b566", "#6ee8bf", "#7e6654", "#6eafe8"];
      for (var i = 0; i < this.hots.tags.length; i++) {
        var tag = {};
        let k = -1 + (2 * (i + 1) - 1) / tagsNum;
        let a = Math.acos(k);
        let b = a * Math.sqrt(tagsNum * Math.PI);
        tag = {
          text: this.hots.tags[i],
          x: this.CX + this.hots.RADIUS * Math.sin(a) * Math.cos(b),
          y: this.CY +  this.hots.RADIUS * Math.sin(a) * Math.sin(b), 
          z: this.hots.RADIUS * Math.cos(a)
        };
        tag.size = 24;
        tags.push(tag);
      }
      this.hots.tags = tags;
      this.hots.playtimeout = setInterval(() => {
        this.rotateX(this.hots.speedX);
        this.rotateY(this.hots.speedY);
      }, 60);
    },
    rotateX(angleX) {
      this.hots.playtime++;
      var cos = Math.cos(angleX);
      var sin = Math.sin(0);
      for (let tag of this.hots.tags) {
        var y1 = (tag.y - this.CY) * cos - tag.z * sin + this.CY;
        var z1 = tag.z * cos + (tag.y - this.CY) * sin;
        tag.y = y1;
        tag.z = z1;
      }
    },
    rotateY(angleY) {
      var cos = Math.cos(angleY);
      var sin = Math.sin(angleY);
      for (let tag of this.hots.tags) {
        var x1 = (tag.x - this.CX) * cos - tag.z * sin + this.CX;
        var z1 = tag.z * cos + (tag.x - this.CX) * sin;
        tag.x = x1;
        tag.z = z1;
      }
    }
  },
  watch: {
    component: {
      handler(newValue, oldValue) {
        this.$nextTick(function() {
          if (this.echart) this.echart.resize();
        });
      },
      deep: true
    }
  }
};
</script>
<style lang="less">
.wordediter {
  border: 0;
  outline: 0;
  width: 94%;
  position: relative;
  height: calc(100% - 10px);
  padding: 0;
  margin: 5px auto;
  display: block;
  box-sizing: border-box;
  background: transparent;
}
.removecomponents {
  position: absolute;
  right: 0px;
  top: 0px;
  font-size: 28px;
  display: none;
  color: #f56c6c;
  z-index: 9999;
  cursor: pointer;
}
.active {
  z-index: 999 !important;
}
.active .removecomponents {
  display: block;
}
.sys-tabel tr {
  font-size: 14px;
}
.sys-tabel td {
  font-size: 12px;
}
.sys-tabel,
.el-table__expanded-cell {
  background: transparent;
}
.sys-tabel th,
.sys-tabel tr {
  background: transparent;
  padding: 0px 0;
}
.sys-tabel td,
.sys-tabel th.is-leaf {
  border-bottom: 0;
}
.el-table--enable-row-hover .el-table__body tr:hover > td {
  background: transparent;
}
.sys-tabel::before {
  height: 0;
}
.sys-tabel .el-table__body-wrapper::-webkit-scrollbar {
  width: 5px;
  background-color: rgba(0, 0, 0, 0);
}

.sys-tabel .el-table__body-wrapper::-webkit-scrollbar-thumb {
  border-radius: 5px;
  -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.3);
  background-color: #555;
}
</style>
